package com.hermes.comics;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.ListActivity;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;

import android.net.Uri;

import android.os.Bundle;
import android.os.Message;

import android.text.Html;
import android.text.InputType;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.DateFormat;

import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.DatePicker;
import android.widget.ImageView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import com.hermes.comics.R;
import com.hermes.comics.data.Constants;
import com.hermes.comics.data.Catalog;
import com.hermes.comics.data.Issue;
import com.hermes.comics.data.IssueTag;
import com.hermes.comics.data.Serie;
import com.hermes.comics.data.SerieTag;
import com.hermes.comics.dialogs.AutoUpdateIssueDialog;
import com.hermes.comics.dialogs.SaveItemDialog;
import com.hermes.comics.utils.ImageUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.HashSet;
import java.util.Set;

public class IssuesActivity extends ListActivity {

  private Serie serie;
  private List<Issue> issues;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Catalog.init(this);

    serie = Catalog.getInstance().getSerie(getSerieKey());
    issues = showOnlyMissing() ? new ArrayList<Issue>(serie.missing()) : serie.issues();

    getActionBar().setDisplayShowCustomEnabled(true);
    getActionBar().setDisplayShowTitleEnabled(true);
    getActionBar().setDisplayUseLogoEnabled(true);
    getActionBar().setTitle(SerieTag.TITLE.value(serie));
    getActionBar().setSubtitle("Key: " + SerieTag.KEY.value(serie) + ", Issues: " + issues.size());

    setListAdapter(new CustomArrayAdapter(this, issues));
    registerForContextMenu(getListView());
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.issues_action_bar_menu, menu);

    MenuItem item = menu.findItem(R.id.menu_issues_only_missing);
    item.setTitle(showOnlyMissing() ? "Show all issues" : "Show missing issues");

    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.menu_issues_only_missing:
        Intent intent = new Intent(this, IssuesActivity.class);
        intent.putExtra(Constants.ISSUES_MODE_KEY,
                        showOnlyMissing() ? Constants.ISSUES_MODE_ALL : Constants.ISSUES_MODE_MISSING);
        intent.putExtra(Constants.SERIE_KEY, getSerieKey());
        finish();
        startActivity(intent);
        break;
      case R.id.menu_update_all_issues:
        AutoUpdateIssueDialog.build(this, serie, (BaseAdapter) getListAdapter()).show();
        break;
    }

    return true;
  }

  @Override
  public void onListItemClick(ListView listView, View view, int position, long id) {
    openContextMenu(view);
  }

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);

    getMenuInflater().inflate(R.menu.edit_issue_menu, menu);

    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
    if (info != null) {
      Issue issue = issues.get(info.position);
      boolean isMissing = "Y".equals(IssueTag.MISSING.value(issue));
      ((MenuItem) menu.findItem(R.id.menu_issue_edit_missing)).setChecked(isMissing);

      boolean isUnread = "N".equals(IssueTag.READ.value(issue));
      ((MenuItem) menu.findItem(R.id.menu_issue_edit_read)).setChecked(!isUnread);
    }
  }

  @Override
  public boolean onContextItemSelected(MenuItem item) {
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

    if (info == null) {
      return false;
    }

    final Issue issue = (Issue) info.targetView.getTag();

    switch (item.getItemId()) {
      case R.id.menu_issue_edit_missing:
        return update(issue, IssueTag.MISSING, "Y".equals(IssueTag.MISSING.value(issue)) ? "N" : "Y");
      case R.id.menu_issue_edit_read:
        return createDialogForDate(issue);
      case R.id.menu_issue_edit_title:
        return createDialog(issue, IssueTag.TITLE);
      case R.id.menu_issue_edit_url:
        return createDialog(issue, IssueTag.URL);
      case R.id.menu_issue_edit_pages:
        return createDialog(issue, IssueTag.PAGES);
      case R.id.menu_issue_edit_img:
        return createDialog(issue, IssueTag.IMG);
      case R.id.menu_issue_edit_date:
        return createDialog(issue, IssueTag.DATE);
      case R.id.menu_issue_autoupdate:
        AutoUpdateIssueDialog.build(this, issue, (BaseAdapter) getListAdapter()).show();
        return true;
      case R.id.menu_issue_web:
        Intent intent = new Intent(this, WebActivity.class);
        intent.putExtra(Constants.SERIE_KEY, IssueTag.SERIE_KEY.value(issue));
        intent.putExtra(Constants.ISSUE_KEY, IssueTag.KEY.value(issue));
        startActivity(intent);

        return true;
    }

    return true;
  }

  private boolean showOnlyMissing() {
    String key = getIntent().getStringExtra(Constants.ISSUES_MODE_KEY);
    return Constants.ISSUES_MODE_MISSING.equals(key);
  }

  private String getSerieKey() {
    return getIntent().getStringExtra(Constants.SERIE_KEY);
  }

  private boolean update(Issue issue, IssueTag tag, String value) {
    issue.setTag(tag, value);

    SaveItemDialog.OnSaveData onSaveData = new SaveItemDialog.OnSaveData() {
      @Override
      public void onSave() {
        BaseAdapter adapter = (BaseAdapter) IssuesActivity.this.getListAdapter();
        adapter.notifyDataSetChanged();
      }
    };

    SaveItemDialog.buildForIssue(this, issue, onSaveData).show();
    return true;
  }

  private boolean createDialogForDate(final Issue issue) {
    Calendar calendar = issue.getReadDate();

    DatePickerDialog.OnDateSetListener listener = new DatePickerDialog.OnDateSetListener() {
      @Override
      public void onDateSet(DatePicker view, int year, int month, int day) {
      }
    };

    DatePickerDialog dialog = new DatePickerDialog(
        this, listener, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)) {
      @Override
      public void onDateChanged(DatePicker view, int year, int month, int day) {
        super.onDateChanged(view, year, month, day);
        setTitle("Read on?");
      }      

      @Override
      public void onClick(DialogInterface dialog, int button) {
        if (button == DialogInterface.BUTTON_POSITIVE) {
          String newValue = getDatePicker().getYear() + "|" + getDatePicker().getMonth()
              + "|" + getDatePicker().getDayOfMonth();
          update(issue, IssueTag.READ, newValue);
        }
      }
    };
    dialog.setTitle("Read on?");
    dialog.setButton(DialogInterface.BUTTON_POSITIVE, "Save", dialog);
    dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", dialog);
    dialog.show();

    return true;
  }

  private boolean createDialog(final Issue issue, final IssueTag tag) {
    final EditText textView = new EditText(this);
    textView.setText(tag.value(issue));

    if (tag == IssueTag.PAGES) {
      textView.setInputType(InputType.TYPE_CLASS_NUMBER);
    }

    DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int id) {
        if (id == DialogInterface.BUTTON_POSITIVE) {  
          update(issue, tag, textView.getText().toString());
        }
      }
    };

    new AlertDialog.Builder(this)
        .setTitle(tag.title())
        .setView(textView)
        .setPositiveButton(android.R.string.ok, listener)
        .setNegativeButton(android.R.string.cancel, listener)
        .create()
        .show();

    return true;
  }

 /**
  * The fragment for each page. BLABLA...
  */
  class CustomArrayAdapter extends ArrayAdapter<Issue> {

    private final List<Issue> issues;
    private final Set<Issue> expandedItems = new HashSet<Issue>();

    public CustomArrayAdapter(Activity activity, List<Issue> issues) {
      super(activity, R.layout.issue_list_item, issues);
      this.issues = issues;
    }

    private LayoutInflater getInflater() {
      return (LayoutInflater) LayoutInflater.from(getContext());
    }

    private Spanned formatIssue(Issue issue) {
      StringBuilder sb = new StringBuilder();

      String subtitle = IssueTag.TITLE.value(issue);
      if (!TextUtils.isEmpty(subtitle)) {
        sb.append(subtitle).append("<br>");
      }

      IssueTag tags[] = { IssueTag.PAGES, IssueTag.DATE };

      String delimiter = "";
      for (IssueTag tag : tags) {
        String value = tag.value(issue);
        if (!TextUtils.isEmpty(value)) {
          sb.append(delimiter).append("<b>").append(tag.title()).append(":</b> ").append(value);
          delimiter = "<br>";
        }
      }

      if (!"N".equals(IssueTag.READ.value(issue))) {
        if ("Y".equals(IssueTag.READ.value(issue))) {
          sb.append("<br><b>Read on </b> <i>NEED UPDATE</i>");
        } else {
          Calendar calendar = issue.getReadDate();
          sb.append("<br><b>Read on </b> ").append(DateFormat.format("yyyy/MMMM", calendar));
        }
      }

      return Html.fromHtml(sb.toString());
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
      final Issue issueView = issues.get(position);

      final Serie catalogSerie = Catalog.getInstance().getSerie(issueView);

      final Issue issue = catalogSerie.getIssue(IssueTag.KEY.value(issueView));

      if (view == null) {
        view = getInflater().inflate(R.layout.issue_list_item, null);
      }

      view.setTag(issue);

      TextView titleView = (TextView) view.findViewById(R.id.title);
      titleView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
      titleView.setText("Issue " + IssueTag.KEY.value(issue));

      boolean isMissing = "Y".equals(IssueTag.MISSING.value(issue));
      boolean isRead = !"N".equals(IssueTag.READ.value(issue));

      View missingView = view.findViewById(R.id.missing);
      missingView.setVisibility(isMissing ? View.VISIBLE : View.GONE);
      
      View readView = view.findViewById(R.id.read);
      readView.setVisibility(isRead ? View.VISIBLE : View.GONE);

      ImageUtils.setImage(issue, (ImageView) view.findViewById(R.id.image));

      TextView extra = (TextView) view.findViewById(R.id.extra);
      extra.setText(formatIssue(issue));

      return view;
    }
  }
}
